Skip to main content

Timeout and Abort in the .NET Engine

This article explains how to use timeout and abort for report cancellation in the embedded .NET Engine.

Overview​

The .NET API exposes per-report cancellation controls:

  • Report.Timeout (seconds)
  • Report.Abort()

These are instance-scoped. If many reports run concurrently, setting timeout or abort on one report instance does not stop other reports.

Timeout Behavior​

Use Report.Timeout to set a runtime limit.

  • 0 means no timeout.
  • Timeout throws net.windward.xmlreport.TimeoutException with mode TIMEOUT.

Precedence and Call Order​

Timeout is honored regardless of whether it is set before or after ProcessSetup().

Order of precedence:

  1. Report.Timeout
  2. report.timeout configuration property

If both are set, Report.Timeout wins.

Abort Behavior​

Use Report.Abort() to cancel a running report from another thread.

  • Abort() signals cancellation and returns immediately.
  • The running report exits at the next checkpoint.
  • Abort throws net.windward.xmlreport.TimeoutException with mode ABORT.

Bounded Observation​

Timeout and abort are checked across long-running phases such as data processing, parsing, layout, chart handling, and output building.

Cancellation is cooperative and checkpoint-based rather than forceful thread termination.

.NET Usage Example​

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using net.windward.api.csharp;
using WindwardInterfaces.net.windward.api.csharp;

public class DotNetTimeoutAbortExample
{
public static void Main()
{
Report.Init();

using (var template = File.OpenRead("template.docx"))
using (var output = File.Open("report.pdf", FileMode.Create))
{
Report report = new ReportPdf(template, output);

// API timeout has highest precedence over report.timeout config property.
report.Timeout = 30;

report.ProcessSetup();

var providers = new Dictionary<string, IReportDataSource>();
// providers.Add("", yourDatasource);

var abortThread = new Thread(() =>
{
Thread.Sleep(5000);
report.Abort();
});
abortThread.IsBackground = true;
abortThread.Start();

try
{
report.ProcessData(providers);
report.ProcessComplete();
}
catch (net.windward.xmlreport.TimeoutException ex)
{
if (ex.getMode() == net.windward.xmlreport.TimeoutException.TIMEOUT)
{
Console.WriteLine("Report timed out");
}
else if (ex.getMode() == net.windward.xmlreport.TimeoutException.ABORT)
{
Console.WriteLine("Report aborted");
}
throw;
}
}
}
}

Logging and Diagnostics​

The engine logs timeout and abort observations to help identify where cancellation was requested and where it was observed.

Best Practices​

  • Prefer Report.Abort() and Report.Timeout over Thread.Abort().
  • Do not share one report instance across multiple unrelated jobs.
  • Catch timeout exceptions and distinguish TIMEOUT from ABORT.
  • Keep resource cleanup in finally blocks for output streams and data connections.